function [array_mask, array_mask_ind, elem_pos] = funcGenLinearArrayMask(nv, pitch, width, array_angle, array_pos, ...
    kgrid)
%Generate array mask used for k-Wave.
%
% Pre-conditions: the step sizes along x-direction and z-direction must be equal !
% 
% # Args:
% - nv: the number of elements.
% - pitch: the center distance between the adjacent elements, unit: [m].
% - width: the width of the element, unit: [m].
% - array_angle: the angle between the array and the x-coordinate, unit: [rad].
% - array_pos: the center position of the array, unit: [m].
% - kgrid: the simulation grids generated by kWaveGrid.
%
% # Returns:
% - array_mask: the generated array mask which is a matrix of size [nx, nz].
% - array_mask_idx: a matrix stores the elements index.
% - elem_pos: the position of the elements in the array, which is a matrix of size [num_elem, 2]. The first column is
% the x-coordinates, and the second column is the z-coordinates.
%

x_vec = kgrid.x_vec;
y_vec = kgrid.y_vec;

elem_x = -nv / 2 : (nv / 2 - 1);
elem_x = elem_x * pitch * cos(array_angle) + array_pos(1);
elem_y = -nv / 2 : (nv / 2 - 1);
elem_y = elem_y * pitch * sin(array_angle) + array_pos(2);
elem_pos = [elem_x', elem_y'];

step_size = mean(diff(x_vec));

[y, x] = meshgrid(y_vec, x_vec);
dis = abs((x - array_pos(1)) * sin(array_angle) - (y - array_pos(2)) * cos(array_angle));
array_mask_ind = zeros(numel(x_vec), numel(y_vec), nv);
for i = 1 : nv
    dis_elem = sqrt((x - elem_pos(i, 1)).^2 + (y - elem_pos(i, 2)).^2);
    mask_tmp = zeros(size(x));
    mask_tmp((dis < step_size / 2) & (dis_elem < width / 2)) = 1;
    array_mask_ind(:, :, i) = mask_tmp * i;
end
array_mask = sum(array_mask_ind, 3);
array_mask(array_mask > 0) = 1;
array_mask_ind = sum(array_mask_ind, 3);

end
